package com.xxl.job.executor.process;

import java.util.ArrayList;
import java.util.List;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.executor.SpringContextUtil;
import com.xxl.job.executor.model.DevInfosModel;
import com.xxl.job.executor.model.GatherDefModel;
import com.xxl.job.executor.model.SignalDefHkModel;
import com.xxl.job.executor.protocol.TCPProtocol;
import com.xxl.job.executor.service.GatherDefService;
import com.xxl.job.executor.service.TemperatureSensingOpticalFiberService;
import com.xxl.job.executor.utils.TransUtils;

public class TemperatureSensingOpticalFiberProcess {
    private TCPProtocol tcpClient;
    private String param;

    public TemperatureSensingOpticalFiberProcess(String param) {
        this.param = param;
    }

    public void collectProcess() throws Exception {
        try {
            for (int t = 0; t < 4000; t++) {
                XxlJobLogger.log("*************************************第" + t + "次******************************");

                // 获取感温光纤分区列表
                List<GatherDefModel> gatherDefModelList = SpringContextUtil.getBean(GatherDefService.class)
                        .findGatherDefModelList(param);

                for (int num = 0; num < gatherDefModelList.size(); num++) {
                    String remark = gatherDefModelList.get(num).getRemark();
                    String[] str = remark.split(",");
                    byte byte8 = (byte) (0xff & Integer.parseInt(str[1], 16)); // 起始地址 高位 16进制
                    byte byte9 = (byte) (0xff & Integer.parseInt(str[2], 16)); // 起始地址 低位 16进制
                    byte byte11 = (byte) (0xff & Integer.parseInt(str[3], 16)); // 读取数量 16进制
                    int pointAddr = Integer.parseInt(str[4]); // 起始地址 10进制
                    String ip = gatherDefModelList.get(num).getCollectIp(); // 获取IP
                    int port = Integer.parseInt(gatherDefModelList.get(num).getCollectPort()); // 获取端口
                    tcpClient = new TCPProtocol(ip, port);
                    if (tcpClient.connect()) {
                        // 初始化采集命令
                        byte[] sendInfo = readStr(byte8, byte9, byte11);
                        // 发送modbus tcp报文
                        tcpClient.sendData(sendInfo);
                        // 接收modbus返回报文
                        byte[] retByte = tcpClient.recvData();

                        String sendStr = TransUtils.getBufHexStr(sendInfo);
                        String retStr = TransUtils.getBufHexStr(retByte);
                        //System.err.println(gatherDefModelList.get(num).getGatherName() + "发送报文 ： " + sendStr);
                        //System.err.println(gatherDefModelList.get(num).getGatherName() + "接收报文 ： " + retStr);

                        if (retStr == null) {
                            XxlJobLogger.log("Modbus Tcp ：接收报文异常，数据为null，" + gatherDefModelList.get(num).getGatherName()
                                    + "发送报文 ： " + sendStr);

                        } else {
                            // 米数
                            Integer metres = Integer.parseInt(retStr.substring(16, 18), 16) / 2;
                            // 每米温度字符串
                            String last = retStr.substring(18);
                            ArrayList<DevInfosModel> dataDevModelArrayList= new ArrayList<DevInfosModel>();
                            int flag = 0;
                            for (int i = 0; i < metres; i++) {

                                SignalDefHkModel temperatureSensingOpticalFiber = new SignalDefHkModel();
                                temperatureSensingOpticalFiber.setGatherId(param);
                                temperatureSensingOpticalFiber.setGatherResId(gatherDefModelList.get(num).getResId());
                                temperatureSensingOpticalFiber.setSignalValue(
                                        String.valueOf(Integer.parseInt(last.substring(i * 4, (i + 1) * 4), 16) / 10.0));
                                temperatureSensingOpticalFiber.setPointAddr(String.valueOf(pointAddr + i));// 寄存器地址
                                if(i==metres-1){
                                    flag = 1;
                                }
                                SpringContextUtil.getBean(TemperatureSensingOpticalFiberService.class)
                                        .save(temperatureSensingOpticalFiber, flag,dataDevModelArrayList);
                            }
                        }
                        tcpClient.close();
                    } else {
                        XxlJobLogger.log("PLC：client创建连接失败，等待10秒重连...，ip: " + ip + " ,port: " + port);
                        Thread.sleep(10000);
                    }
                }

                XxlJobLogger.log("*************************************暂停20秒******************************");
                Thread.sleep(20000);
            }
        } catch (Exception e) {
            if (e instanceof InterruptedException) {
                throw e;
            }
            e.printStackTrace();
        }
    }

    /**
     * 读取 功能码
     */
    private byte[] readStr(int byte8, int byte9, int byte11) {
        byte[] sendInfo = new byte[12];
        sendInfo[0] = 00;
        sendInfo[1] = 02;
        sendInfo[2] = 00;
        sendInfo[3] = 00;
        sendInfo[4] = 00;
        sendInfo[5] = 06; // 后面位数
        sendInfo[6] = 02; // 设备地址
        sendInfo[7] = 03; // 功能码
        sendInfo[8] = (byte) byte8; // 寄存器起始地址 高八位
        sendInfo[9] = (byte) byte9; // 寄存器起始地址 低八位
        sendInfo[10] = 00; // 读寄存器数量 高八位
        sendInfo[11] = (byte) byte11; // 读寄存器数量 低八位

        return sendInfo;
    }

    /**
     * 单个写入 功能码 05
     */
    public byte[] writeStr(String cmdStr) {
        byte[] sendInfo = new byte[12];
        sendInfo[0] = 0x00;
        sendInfo[1] = 0x05;
        sendInfo[2] = 0x00;
        sendInfo[3] = 0x00;
        sendInfo[4] = 0x00;
        sendInfo[5] = 0x06; // 后面位数
        sendInfo[6] = 0x01; // 设备地址
        sendInfo[7] = 0x05; // 功能码
        sendInfo[8] = 0x00; // 寄存器起始地址 高八位
        sendInfo[9] = 0x01; // 寄存器起始地址 低八位

        if (cmdStr.equals("true")) {
            sendInfo[10] = (byte) 0xFF; // 寄存器数量 高八位
        } else {
            sendInfo[10] = 0x00; // 寄存器数量 高八位
        }

        sendInfo[11] = 0x00; // 读寄存器数量 低八位

        return sendInfo;
    }
}
